//
//  UIGridView.m
//  GridViewUsingTableView
//
//  Created by Manoj Babu on 23/09/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "UIGridView.h"

#define CELL_IDENTIFIER @"gridviewcell"

@interface UIGridView() 
-(void)setup;
-(void)initialize;
-(UIGridViewCell *)cellForGridPath:(UIGridPath *)gridPath;
@end

@implementation UIGridPath
@synthesize row, column, index;
-(id)initWithRow:(NSInteger)_row column:(NSInteger)_column index:(NSInteger)_index
{
    self = [super init];
    if(self)
    {
        row = _row;
        column = _column;
        index = _index;
    }
    return self;
}

@end

@implementation UIGridView

@synthesize delegate;
@synthesize dataSource;
@synthesize cellHeight;
@synthesize cellWidth;

-(id)init
{
    self = [super init];
    if(self)
    {
        [self initialize];
    }
    return self;
}

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        [self initialize];
    }
    return self;
}

-(UIGridViewCell *)dequeueCellAtGridPath:(UIGridPath *)gridPath
{
    /*NSIndexPath *indexPath = [NSIndexPath indexPathForRow:gridPath.row inSection:0];
    UITableViewCell *dequeueCell = nil;
    dequeueCell = [_tableView cellForRowAtIndexPath:indexPath];*/
    UIGridViewCell *gridViewCell = nil;
    if(_dequeuedRow != nil)
    {
        /*gridViewCell = (UIGridViewCell *)[_dequeuedCell.contentView viewWithTag:gridPath.column + 100];
        if(![gridViewCell isKindOfClass:[UIGridViewCell class]])
            gridViewCell = nil;*/
        gridViewCell = [_dequeuedRow cellAtColumn:gridPath.column];
    }
    return gridViewCell;
}

-(void)reloadData
{
    [_tableView reloadData];
}

#pragma UITableView dataSource methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if([dataSource respondsToSelector:@selector(numberOfItemsInGridView:)])
    {
        nCells = [dataSource numberOfItemsInGridView:self];
        [self setup];
        return nRows;
    }
    return 0;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIGridViewRow *row = nil;
    [_dequeuedRow release];
    _dequeuedRow = nil;
    row = (UIGridViewRow *)[_tableView dequeueReusableCellWithIdentifier:CELL_IDENTIFIER];
    if(row == nil)
    {
        row =[[[UIGridViewRow alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CELL_IDENTIFIER] autorelease];
        row.delegate = self;
    }
    else
    {
        [_dequeuedRow release];
        _dequeuedRow = [row retain];
    }
    NSUInteger actualRow = indexPath.row;
    row.row = actualRow;
    for (int column = 1; column <= nColumns; column++) 
    {
        //Find index for row major matrix/grid
        NSUInteger cellIndex = (actualRow * nColumns) + column;
        cellIndex -= 1;
        if(cellIndex < nCells)
        {
            UIGridPath *gridPath = [[UIGridPath alloc] initWithRow:indexPath.row column:column - 1 index:cellIndex];
            UIGridViewCell *gridViewCell = [self cellForGridPath:gridPath];
            //[cell.contentView addSubview:gridViewCell];
            [row addCell:gridViewCell atColumn:gridPath.column];
            [gridPath release];
        }
        else
        {
            NSLog(@"Out of bound");
            break;
        }
    }
    return row;
}

#pragma UITableView delegate methods

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"Select :- %d",[indexPath row]);
}

#pragma Private methods

-(void)setup
{
    CGSize viewSize = self.frame.size;
    _tableView.frame = CGRectMake(0, 0, viewSize.width, viewSize.height);
    nColumns = viewSize.width/cellWidth;
    gap = (viewSize.width - (cellWidth * nColumns))/(nColumns + 1);
    rHeight = cellHeight + gap;
    nRows = ceil(nCells/nColumns);
    _tableView.rowHeight = rHeight;
}

-(void)initialize
{
    _tableView = [[UITableView alloc] initWithFrame:self.frame style:UITableViewStylePlain];
    _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    //_tableView.separatorColor = [UIColor blackColor];
    _tableView.dataSource = self;
    _tableView.delegate = self;
    cellHeight = 75;
    cellWidth = 75;
    _dequeuedRow = nil;
    [self addSubview:_tableView];
}

-(UIGridViewCell *)cellForGridPath:(UIGridPath *)gridPath
{
    
    UIGridViewCell *gridViewCell = [self.dataSource gridView:self cellForIndexAtGridPath:gridPath];
    gridViewCell.tag = gridPath.column + 100;
    CGPoint position = CGPointMake((gridPath.column * cellWidth) + ((gridPath.column + 1) * gap), gap);
    //gridViewCell.frame = CGRectMake(position.x, position.y, cellWidth, cellHeight);
    [gridViewCell setCellFram:CGRectMake(position.x, position.y, cellWidth, cellHeight)];
    //NSLog(@"Row :- %d, column :- %d, index :- %d",gridPath.row,gridPath.column, gridPath.index);
    NSLog(@"Row :- %d, column :- %d, X :- %f, Y :- %f",gridPath.row,gridPath.column, position.x, position.y);
    
    return gridViewCell;
}

#pragma UIGridViewRowDelegate methods

-(void)gridViewRow:(UIGridViewRow *)row didSelectCellAtGridPath:(UIGridPath *)gridPath
{
    if([self.delegate conformsToProtocol:@protocol(UIGridViewDelegate)])
        [self.delegate didSelectCellAtGridPath:gridPath];
}

@end

@implementation UIGridViewRow

@synthesize row;
@synthesize delegate;

-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if(self)
    {
        cells = [[NSMutableArray alloc] init];
    }
    return self;
}
-(UIGridViewCell *)cellAtColumn:(NSUInteger)column
{
    if([cells count] > column)
    {
        return [cells objectAtIndex:column];
    }
    return nil;
}

-(void)addCell:(UIGridViewCell *)cell atColumn:(NSUInteger)column
{
    if (cell != nil && cell.superview == nil)
    {
        //[cells addObject:cell];
        [cells insertObject:cell atIndex:column];
        [self.contentView addSubview:cell];
        cell.delegate = self;
    }
}

-(void)dealloc
{
    [cells release];
    [super dealloc];
}

#pragma UIGridViewCell delegate methods

-(void)didSelectCell:(UIGridViewCell *)cell withIndex:(NSInteger)index
{
    if([cells containsObject:cell])
    {
        int column = [cells indexOfObject:cell];
        UIGridPath *gridPath = [[UIGridPath alloc] initWithRow:row column:column index:index];
        if([self.delegate conformsToProtocol:@protocol(UIGridViewRowDelegate)])
            [self.delegate gridViewRow:self didSelectCellAtGridPath:gridPath];
        [gridPath release];
    }
                            
}

@end
